/*
 * Copyright 2010, The PLDesktop Development Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
#ifndef PLITERATOR_H
#define PLITERATOR_H

#include <tools/PLIIterator.h>
#ifndef VECTOR_WITHOUT_PLOBJECT
#include <kernel/PLObject.h>
#endif

namespace PLSDK {

    /**
     * The iterator.
     */
    template<typename T>
    class PLIterator
#ifndef VECTOR_WITHOUT_PLOBJECT
        : public virtual PLObject
#endif
    {
    public:
        /**
         * Constructor.
         *
         * @param it The interator interface to work with.
         */
        inline PLIterator(PLIIterator<T> *it) :
#ifndef VECTOR_WITHOUT_PLOBJECT
            PLObject(),
#endif
            m_iterator(it), m_pos(0) {}
        /**
         * Copy Constructor.
         *
         * @param it The iterator to copy.
         */
        inline PLIterator(const PLIterator<T> &it) :
#ifndef VECTOR_WITHOUT_PLOBJECT
            PLObject(),
#endif
            m_iterator(it.m_iterator), m_pos(it.m_pos) {}
        /**
         * Have the current position have a next object.
         *
         * @return true if the current position have a next object.
         */
        inline plbool hasNext() {
            return m_iterator->hasNext(m_pos);
        }
        /**
         * Have the current position have a previous object.
         *
         * @return true if the current position have a previous object.
         */
        inline plbool hasPrevious() {
            return m_iterator->hasPrevious(m_pos);
        }
        /**
         * The next object of the vector.
         *
         * @return The next object.
         */
        inline T next() {
            m_pos++;
            return m_iterator->next(m_pos - 1);
        }
        /**
         * The previous object of the vector.
         *
         * @return The previous object.
         */
        inline T previous() {
            m_pos--;
            return m_iterator->previous(m_pos + 1);
        }
        /**
         * Return the current object.
         *
         * @return The object.
         */
        inline T current() {
            return m_iterator->current(m_pos);
        }
        /**
         * Remove the current element of the operator.
         *
         * @todo move the position to a better position if it was the last element.
         */
        inline void removeElement() {
            m_iterator->removeElement(m_pos - 1);
        }
        /**
         * Reset the iterator.
         */
        inline void reset() {
            m_pos = 0;
        }
        /**
         * Is the iterator not on the position with the node.
         *
         * @param node The node to test for.
         * @return True if it was not that position.
         */
        inline plbool operator != (T node) {
            return m_iterator->current(m_pos) != node;
        }
        /**
         * Is the iterator on the position with the node.
         *
         * @param node The node to test for.
         * @return True if it was that position.
         */
        plbool operator == (T node) {
            return m_iterator->current(m_pos) == node;
        }
    private:
        PLIIterator<T> *m_iterator;
        int m_pos;
    };

}

#endif
